import sys
from concurrent.futures import thread
import os
import socket
import threading
import time
import queue
import keyboard

"""
UDP客户端自动测试程序
1、UDP客户端接收任务，接收数据，并将数据保存到接收队列中
2、UDP客户端发送任务，将接收队列中的数据自动发送至UDP服务器，从而进行回环测试
"""

### UDP服务器地址和端口，按实际环境设置
udp_server_host = "127.0.0.1"
udp_server_port = 9090

### UDP客户端接收和发送缓冲区，同步队列
socket_rec_queue = queue.Queue(0)
socket_send_queue = queue.Queue(0)

### 是否提示调试信息
SYS_DEBUG_ENABLE = True

def udp_send_task(udp):
    global SYS_DEBUG_ENABLE
    udp.sendall(b'Hello UDP server')
    while True:
        try:
            while (not socket_send_queue.empty()):
                data = socket_send_queue.get()

                if len(data)<=0:
                    continue

                udp.sendall(data)
                if SYS_DEBUG_ENABLE:
                    pass
                    #print("LOG UDP Client Send: %d" % (len(data)))
                    #print("%s" % (str(data, "UTF-8"),))
        except:
            print("UDP Client error!")
            socket_rec_queue.queue.clear()
                
        time.sleep(0.005)

def udp_rec_task(udp):
    udp_send_td = threading.Thread(target=udp_send_task, args=(udp,))
    udp_send_td.start()
    print("UDP Client start send and rec:---")

    while True:
        data = udp.recv(4096)

        if len(data)<=0:
            continue

        socket_rec_queue.put((udp, data))

        if SYS_DEBUG_ENABLE: 
            #print("LOG UDP Client Rec: %d" % (len(data)))
            print("%s" % (str(data, "UTF-8"),), end='')

def udp_auto_send(a):
    if a<1000: a = 1000
    while True:
        socket_send_queue.put(b"Hello UDP Server\n")
        time.sleep(a/1000)


### 监听按键，退出程序
def app_exit(udp):
    udp.close()
    print("Key: CTRL+X")
    os._exit(0)

if __name__ == '__main__':
    print("<...UDP Client REC MSG...>\n")
    print("Exit: CTRL+X")

    arg_len = len(sys.argv)
    if arg_len==1:
        print("请指定服务器地址！！！")
    else:
        for i in range(arg_len):
            if 1==i:
                udp_server_host = sys.argv[1]
            elif 2==i:
                udp_server_port = int(sys.argv[2])

        print("Server: %s, Port: %d" % (udp_server_host, udp_server_port))

        udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udp_client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        udp_client.connect((udp_server_host, udp_server_port))

        udp_rec_td = threading.Thread(target=udp_rec_task, args=(udp_client,))
        udp_rec_td.start()

        auto_send_td = threading.Thread(target=udp_auto_send, args=(5000,))
        auto_send_td.start()

        keyboard.add_hotkey("ctrl+x", app_exit, args=(udp_client,))

    while True:
        time.sleep(60)
        print("Clear Console...")
        os.system('cls')


